package services.security;

import java.util.*;

import org.apache.commons.lang3.StringUtils;

import dto.http.*;
import dto.user.*;

import services.exception.*;
import services.user.AniLocalUserRegService;
import utils.*;
import models.user.*;

public class AniLocalUserAuthService extends AniSecurityService {

	//auth user
	public static String authenticateUser(Map<String, String> reqArgs){
		
		LocalUserAuthInfoDto localUserAuthInfo = getUserAuthInfoFromRequest(reqArgs);
		checkLocalUserAuthInfo(localUserAuthInfo);
		regAuthedUserInfo(localUserAuthInfo);
		return "USER_AUTHENTICATED";
		
	}
	
	//get user info
	protected static LocalUserAuthInfoDto getUserAuthInfoFromRequest(Map<String, String> reqArgs) {
		LocalUserAuthInfoDto userAuthInfo = null;
		try {
			String email = reqArgs.get("email");
			Long reqId = Long.parseLong(reqArgs.get("reqId"));
			String authCode = reqArgs.get("authCode");
			Boolean isSave = null;
			if(StringUtils.isEmpty(reqArgs.get("isSave"))){
				isSave = Boolean.parseBoolean(reqArgs.get("isSave"));
			}else{
				isSave = false;
			}
			
			userAuthInfo = new LocalUserAuthInfoDto(email, reqId, authCode, isSave);
		} catch (Exception e) {
			throw new AniAuthException("USER_AUTH_INFO_ARGS_ILLEGAL");
		}
		
		return userAuthInfo;
	}
	
	//check user info legality
	protected static void checkLocalUserAuthInfo(LocalUserAuthInfoDto userAuthInfo) {
		
		//need catch in controller
		checkReqIdLegality(userAuthInfo.reqId);
		checkRequiredUserAuthInfo(userAuthInfo);
		AniPatternUtils.checkEmailFormatLegality(userAuthInfo.email);
		
		AniUser curUser = getUserInfoWithEmail(userAuthInfo.email);
		String authCodeMD5 = getLocalUserAuthCodeMD5(curUser, userAuthInfo);
		checkAuthCodeLegality(userAuthInfo, authCodeMD5);
		
	}
	private static void checkRequiredUserAuthInfo(LocalUserAuthInfoDto userAuthInfo) {
		if(StringUtils.isEmpty(userAuthInfo.email)){
			throw new AniAuthException("EMAIL_IS_REQUIRED");
		}
		if(StringUtils.isEmpty(userAuthInfo.authCode)){
			throw new AniAuthException("AUTH_CODE_IS_REQUIRED");
		}
	}
	private static void checkAuthCodeLegality(LocalUserAuthInfoDto userAuthInfo, String expAuthCode) {
		if(!userAuthInfo.authCode.trim().equals(expAuthCode)){
			throw new AniAuthException("USER_AUTH_CODE_ILLEGAL");
		}
	}
	
	private static String getLocalUserAuthCodeMD5(AniUser curUser, LocalUserAuthInfoDto userAuthInfo) {
		
		String md5Pwd = curUser.password;
		String serverAuthCode = curUser.email + md5Pwd + userAuthInfo.reqId.toString();
		String serverAuthCodeMD5 = SecureUtils.generateMD5String(serverAuthCode);
		
		return serverAuthCodeMD5;
	}
	
	//register user info as cookie in client
  	private static void regAuthedUserInfo(LocalUserAuthInfoDto userAuthInfo) {
  		AniCookieDto userInfoCookie = new AniCookieDto(MVCUtils.USER_KEY, userAuthInfo.email);
  		try {
  			if(userAuthInfo.isSave != null && userAuthInfo.isSave != false){
  				userInfoCookie.lifetime = MVCUtils.COOKIE_MAX_AGE;
  			}else{
  				userInfoCookie.lifetime = 0;
  			}
  			MVCUtils.pushClientCookie(userInfoCookie);
  		} catch (Exception e) {
  			throw new AniAuthException("USER_COOKIE_REGISTER_FAILED");
  		}
  	}
	
}
